import { boot } from 'quasar/wrappers';
import axios, { AxiosInstance } from 'axios';
import { Dialog } from 'quasar';
import { useGlobalStore } from 'stores/global-store';
import { useUserStore } from 'stores/user-store';

declare module '@vue/runtime-core' {
  interface ComponentCustomProperties {
    $axios: AxiosInstance;
    $api: AxiosInstance;
  }
}
const api = axios.create({ baseURL: import.meta.env.VITE_BASE_API });

export default boot(({ app, router, store }) => {
  const globalStore = useGlobalStore();
  const userStore = useUserStore();
  // for use inside Vue files (Options API) through this.$axios and this.$api
  app.config.globalProperties.$axios = axios;
  // ^ ^ ^ this will allow you to use this.$axios (for Vue Options API form)
  //       so you won't necessarily have to import axios in each vue file

  app.config.globalProperties.$api = api;
  // ^ ^ ^ this will allow you to use this.$api (for Vue Options API form)
  //       so you can easily perform requests against your app's API
  api.interceptors.request.use((config) => {
    /***
     * if user logged in add user's token to header
     */
    if (userStore.token) {
      config.headers!.token = userStore.token;
    }
    if (config.data) {
      if (config.data.page) {
        config.data.page -= 1;
      }
    }
    globalStore.isLoading = true;
    return config;
  });
  api.interceptors.response.use((config) => {
    globalStore.isLoading = false;
    if (config.status !== 200) {
      Dialog.create({
        title: `Network Error: ${config.status}`,
        message: config.statusText,
        persistent: true,
      });
      throw new Error('Network Error');
    }
    const data = config.data;
    console.log(`${config.config.url}->:`, data);
    if (data) {
      if (data.code === 200) {
        if (data.page) {
          data.page.page += 1;
        }
      }
      return data;
    } else {
      throw new Error('reponse.data is null');
    }
  });
});

export { axios, api };

export interface IResponse<T> {
  code: number;
  data: T;
  msg: string;
  page?: IPage;
}
export interface IPage {
  page?: number;
  size?: number;
  total?: number;
}
